package com.swing.sky.web.generator.util;

import com.swing.sky.web.generator.config.GenConfig;
import com.swing.sky.web.generator.constant.ModuleConstants;
import com.swing.sky.web.generator.domain.Module;
import com.swing.sky.web.generator.domain.ModuleHouse;
import com.swing.sky.web.generator.domain.Table;
import com.swing.sky.web.generator.domain.GenColumn;
import org.apache.velocity.VelocityContext;

import java.util.List;

/**
 * @author swing
 */
public class VelocityContextBuilder {
    /**
     * 使用适配器模式找到对应的上下文
     */
    public static VelocityContext buildVelocityContext(List<ModuleHouse> moduleHouses, ModuleHouse moduleHouse, Module module) {
        if (module.getModuleName().equalsIgnoreCase(ModuleConstants.DOMAIN)) {
            return buildVelocityContextDO(moduleHouse.getTable(), moduleHouse.getColumns(), module);
        }
        if (module.getModuleName().equalsIgnoreCase(ModuleConstants.BASIC_DOMAIN)) {
            return buildVelocityContextBasicDO(module);
        }
        if (module.getModuleName().equalsIgnoreCase(ModuleConstants.DOMAIN_BASIC)) {
            return buildVelocityContextDOBasic(moduleHouse.getTable(), moduleHouse.getColumns(), module, moduleHouse.getModules());
        }
        if (module.getModuleName().equalsIgnoreCase(ModuleConstants.BASIC_DAO)) {
            return buildVelocityContextXBasicDAO(module);
        }
        if (module.getModuleName().equalsIgnoreCase(ModuleConstants.BASIC_SERVICE)) {
            return buildVelocityContextXBasicService(module);
        }
        if (module.getModuleName().equalsIgnoreCase(ModuleConstants.BASIC_MAPPER)) {
            return buildVelocityContextXBasicMapper(module, moduleHouse.getModules());
        }
        if (module.getModuleName().equalsIgnoreCase(ModuleConstants.DAO_BASIC)) {
            return buildVelocityContextXDAOBasic(moduleHouse.getTable(), module, moduleHouse.getModules());
        }
        if (module.getModuleName().equalsIgnoreCase(ModuleConstants.DAO)) {
            return buildVelocityContextXDAO(moduleHouse.getTable(), module, moduleHouse.getModules());
        }
        if (module.getModuleName().equalsIgnoreCase(ModuleConstants.MAPPER_BASIC)) {
            return buildVelocityContextXMapperBasic(moduleHouse.getTable(), moduleHouse.getColumns(), module, moduleHouse.getModules());
        }
        if (module.getModuleName().equalsIgnoreCase(ModuleConstants.MAPPER)) {
            return buildVelocityContextXMapper(moduleHouse.getTable(), moduleHouse.getColumns(), module, moduleHouse.getModules());
        }
        if (module.getModuleName().equalsIgnoreCase(ModuleConstants.SERVICE)) {
            return buildVelocityContextService(moduleHouse.getTable(), module, moduleHouse.getModules());
        }
        if (module.getModuleName().equalsIgnoreCase(ModuleConstants.SERVICE_BASIC)) {
            return buildVelocityContextServiceBasic(moduleHouse.getTable(), module, moduleHouse.getModules());
        }
        if (module.getModuleName().equalsIgnoreCase(ModuleConstants.SERVICE_IMPL)) {
            return buildVelocityContextServiceImpl(moduleHouse.getTable(), module, moduleHouse.getModules());
        }
        if (module.getModuleName().equalsIgnoreCase(ModuleConstants.BASIC_LINK_DAO)) {
            return buildVelocityContextBasicLinkDAO(module);
        }
        if (module.getModuleName().equalsIgnoreCase(ModuleConstants.DAO_LINK)) {
            ModuleHouse leftModule = null;
            ModuleHouse rightModule = null;
            for (ModuleHouse house : moduleHouses) {
                if (house.getHoseName().equalsIgnoreCase(moduleHouse.getLeftHouseName())) {
                    leftModule = house;
                }
                if (house.getHoseName().equalsIgnoreCase(moduleHouse.getRightHouseName())) {
                    rightModule = house;
                }
            }
            assert leftModule != null;
            return buildVelocityContextDAOLink(leftModule, module, rightModule, moduleHouse.getModules());
        }
        if (module.getModuleName().equalsIgnoreCase(ModuleConstants.LINK_MAPPER)) {
            ModuleHouse leftModule = null;
            ModuleHouse rightModule = null;
            for (ModuleHouse house : moduleHouses) {
                if (house.getHoseName().equalsIgnoreCase(moduleHouse.getLeftHouseName())) {
                    leftModule = house;
                }
                if (house.getHoseName().equalsIgnoreCase(moduleHouse.getRightHouseName())) {
                    rightModule = house;
                }
            }
            assert leftModule != null;
            return buildVelocityContextLinkMapper(leftModule, module, rightModule, moduleHouse, moduleHouse.getModules());
        }
        return null;
    }

    public static VelocityContext buildVelocityContextLinkMapper(ModuleHouse leftModule, Module module, ModuleHouse rightModule, ModuleHouse moduleHouse, List<Module> modules) {
        VelocityContext velocityContext = new VelocityContext();
        for (Module m : leftModule.getModules()) {
            if (m.getModuleName().equalsIgnoreCase(ModuleConstants.DOMAIN) || m.getModuleName().equalsIgnoreCase(ModuleConstants.DOMAIN_BASIC)) {
                velocityContext.put("leftDoPackage", m.getPackageName() + "." + m.getFileName());
            }
            if (m.getModuleName().equalsIgnoreCase(ModuleConstants.DAO) || m.getModuleName().equalsIgnoreCase(ModuleConstants.DAO_BASIC)) {
                velocityContext.put("leftDaoPackage", m.getPackageName() + "." + m.getFileName());
            }
        }
        for (Module m : rightModule.getModules()) {
            if (m.getModuleName().equalsIgnoreCase(ModuleConstants.DOMAIN) || m.getModuleName().equalsIgnoreCase(ModuleConstants.DOMAIN_BASIC)) {
                velocityContext.put("rightDoPackage", m.getPackageName() + "." + m.getFileName());
            }
            if (m.getModuleName().equalsIgnoreCase(ModuleConstants.DAO) || m.getModuleName().equalsIgnoreCase(ModuleConstants.DAO_BASIC)) {
                velocityContext.put("rightDaoPackage", m.getPackageName() + "." + m.getFileName());
            }
        }
        for (Module module1 : modules) {
            if (module1.getModuleName().equalsIgnoreCase(ModuleConstants.DOMAIN)) {
                velocityContext.put("doPackage", module1.getPackageName() + "." + module1.getFileName());
            }
            if (module1.getModuleName().equalsIgnoreCase(ModuleConstants.DAO_LINK)) {
                velocityContext.put("daoLinkPackageName", module1.getPackageName() + "." + module1.getFileName());
            }
        }
        velocityContext.put("columns", moduleHouse.getColumns());
        velocityContext.put("tableName", moduleHouse.getTable().getTableName());
        velocityContext.put("oneColumn", moduleHouse.getColumns().get(0).getColumnName());
        velocityContext.put("twoColumn", moduleHouse.getColumns().get(1).getColumnName());
        velocityContext.put("oneProperty", moduleHouse.getColumns().get(0).getPropertyName());
        velocityContext.put("twoProperty", moduleHouse.getColumns().get(1).getPropertyName());
        return velocityContext;
    }

    public static VelocityContext buildVelocityContextDAOLink(ModuleHouse leftModule, Module module, ModuleHouse rightModule, List<Module> modules) {
        VelocityContext velocityContext = new VelocityContext();
        velocityContext.put("packageName", module.getPackageName());
        velocityContext.put("className", module.getFileName());
        for (Module m : leftModule.getModules()) {
            if (m.getModuleName().equalsIgnoreCase(ModuleConstants.DOMAIN) || m.getModuleName().equalsIgnoreCase(ModuleConstants.DOMAIN_BASIC)) {
                velocityContext.put("leftDoPackage", m.getPackageName() + "." + m.getFileName());
                velocityContext.put("leftDoClassName", m.getFileName());
            }
        }
        for (Module m : rightModule.getModules()) {
            if (m.getModuleName().equalsIgnoreCase(ModuleConstants.DOMAIN) || m.getModuleName().equalsIgnoreCase(ModuleConstants.DOMAIN_BASIC)) {
                velocityContext.put("rightDoPackage", m.getPackageName() + "." + m.getFileName());
                velocityContext.put("rightDoClassName", m.getFileName());
            }
        }
        for (Module module1 : modules) {
            if (module1.getModuleName().equalsIgnoreCase(ModuleConstants.DOMAIN)) {
                velocityContext.put("doPackage", module1.getPackageName() + "." + module1.getFileName());
                velocityContext.put("doClassName", module1.getFileName());
            }
            if (module1.getModuleName().equalsIgnoreCase(ModuleConstants.BASIC_LINK_DAO)) {
                velocityContext.put("basicLinkDAOPackageName", module1.getPackageName() + "." + module1.getFileName());
                velocityContext.put("basicLinkDAOClassName", module1.getFileName());
            }
        }
        return velocityContext;
    }

    /**
     * 构建渲染BasicDAO.java.vm需要的上下文
     */
    public static VelocityContext buildVelocityContextBasicLinkDAO(Module module) {
        VelocityContext velocityContext = new VelocityContext();
        velocityContext.put("packageName", module.getPackageName());
        velocityContext.put("className", module.getFileName());
        return velocityContext;
    }

    /**
     * 构建渲染ServiceImpl.java.vm需要的上下文
     */
    public static VelocityContext buildVelocityContextServiceImpl(Table table, Module module, List<Module> modules) {
        VelocityContext velocityContext = new VelocityContext();
        for (Module module1 : modules) {
            if (module1.getModuleName().equalsIgnoreCase(ModuleConstants.SERVICE) || module1.getModuleName().equalsIgnoreCase(ModuleConstants.SERVICE_BASIC)) {
                velocityContext.put("ServicePackageName", module1.getPackageName() + "." + module1.getFileName());
                velocityContext.put("ServiceClassName", module1.getFileName());
            }
            if (module1.getModuleName().equalsIgnoreCase(ModuleConstants.DOMAIN) || module1.getModuleName().equalsIgnoreCase(ModuleConstants.DOMAIN_BASIC)) {
                velocityContext.put("DOPackageName", module1.getPackageName() + "." + module1.getFileName());
                velocityContext.put("DOClassName", module1.getFileName());
                velocityContext.put("DOPropertyName", MapUtils.toLowerCaseName(module1.getFileName()));
            }
            if (module1.getModuleName().equalsIgnoreCase(ModuleConstants.DAO) || module1.getModuleName().equalsIgnoreCase(ModuleConstants.DAO_BASIC)) {
                velocityContext.put("DAOPackageName", module1.getPackageName() + "." + module1.getFileName());
                velocityContext.put("DAOClassName", module1.getFileName());
                velocityContext.put("DAOPropertyName", MapUtils.toLowerCaseName(module1.getFileName()));
            }
        }
        velocityContext.put("author", GenConfig.getAuthor());
        velocityContext.put("className", module.getFileName());
        velocityContext.put("packageName", module.getPackageName());
        velocityContext.put("tableComment", table.getTableComment());
        return velocityContext;
    }

    /**
     * 构建渲染Service_BASIC.java.vm需要的上下文
     */
    public static VelocityContext buildVelocityContextServiceBasic(Table table, Module module, List<Module> modules) {
        VelocityContext velocityContext = new VelocityContext();
        for (Module module1 : modules) {
            if (module1.getModuleName().equalsIgnoreCase(ModuleConstants.DOMAIN) || module1.getModuleName().equalsIgnoreCase(ModuleConstants.DOMAIN_BASIC)) {
                velocityContext.put("DOPackageName", module1.getPackageName() + "." + module1.getFileName());
                velocityContext.put("DOClassName", module1.getFileName());
            }
            if (module1.getModuleName().equalsIgnoreCase(ModuleConstants.BASIC_SERVICE)) {
                velocityContext.put("ServicePackageName", module1.getPackageName() + "." + module1.getFileName());
                velocityContext.put("ServiceClassName", module1.getFileName());
            }
        }
        velocityContext.put("author", GenConfig.getAuthor());
        velocityContext.put("className", module.getFileName());
        velocityContext.put("packageName", module.getPackageName());
        velocityContext.put("tableComment", table.getTableComment());
        return velocityContext;
    }

    /**
     * 构建渲染Service.java.vm需要的上下文
     */
    public static VelocityContext buildVelocityContextService(Table table, Module module, List<Module> modules) {
        VelocityContext velocityContext = new VelocityContext();
        for (Module module1 : modules) {
            if (module1.getModuleName().equalsIgnoreCase(ModuleConstants.DOMAIN)) {
                velocityContext.put("DOPackageName", module1.getPackageName() + "." + module1.getFileName());
                velocityContext.put("DOClassName", module1.getFileName());
            }
        }
        velocityContext.put("author", GenConfig.getAuthor());
        velocityContext.put("className", module.getFileName());
        velocityContext.put("packageName", module.getPackageName());
        velocityContext.put("tableComment", table.getTableComment());
        return velocityContext;
    }

    /**
     * 构建渲染BasicDO.java.vm需要的上下文
     */
    public static VelocityContext buildVelocityContextBasicDO(Module module) {
        VelocityContext velocityContext = new VelocityContext();
        velocityContext.put("packageName", module.getPackageName());
        return velocityContext;
    }

    /**
     * 构建渲染DO.java.vm需要的上下文
     */
    public static VelocityContext buildVelocityContextDO(Table table, List<GenColumn> columns, Module module) {
        VelocityContext velocityContext = new VelocityContext();
        velocityContext.put("packageName", module.getPackageName());
        velocityContext.put("tableName", table.getTableName());
        velocityContext.put("tableComment", table.getTableComment());
        velocityContext.put("author", GenConfig.getAuthor());
        velocityContext.put("className", module.getFileName());
        velocityContext.put("columns", columns);
        return velocityContext;
    }

    /**
     * 构建渲染DO_BASIC.java.vm需要的上下文
     */
    public static VelocityContext buildVelocityContextDOBasic(Table table, List<GenColumn> columns, Module module, List<Module> modules) {
        List<GenColumn> collect = MapUtils.filterBasicColumns(columns);
        VelocityContext velocityContext = new VelocityContext();
        for (Module module1 : modules) {
            if (module1.getModuleName().equalsIgnoreCase(ModuleConstants.BASIC_DOMAIN)) {
                velocityContext.put("DOPackageName", module1.getPackageName() + "." + module1.getFileName());
                velocityContext.put("DOClassName", module1.getFileName());
            }
        }
        velocityContext.put("packageName", module.getPackageName());
        velocityContext.put("tableName", table.getTableName());
        velocityContext.put("tableComment", table.getTableComment());
        velocityContext.put("author", GenConfig.getAuthor());
        velocityContext.put("className", module.getFileName());
        velocityContext.put("columns", collect);
        return velocityContext;
    }


    /**
     * 构建渲染DAO_BASIC.java.vm需要的上下文
     */
    public static VelocityContext buildVelocityContextXDAOBasic(Table table, Module module, List<Module> modules) {
        VelocityContext velocityContext = new VelocityContext();
        for (Module module1 : modules) {
            if (module1.getModuleName().equalsIgnoreCase(ModuleConstants.DOMAIN) || module1.getModuleName().equalsIgnoreCase(ModuleConstants.DOMAIN_BASIC)) {
                velocityContext.put("DOPackageName", module1.getPackageName() + "." + module1.getFileName());
                velocityContext.put("DOClassName", module1.getFileName());
            }
            if (module1.getModuleName().equalsIgnoreCase(ModuleConstants.BASIC_DAO)) {
                velocityContext.put("DAOPackageName", module1.getPackageName() + "." + module1.getFileName());
                velocityContext.put("DAOClassName", module1.getFileName());
            }
        }
        velocityContext.put("author", GenConfig.getAuthor());
        velocityContext.put("className", module.getFileName());
        velocityContext.put("packageName", module.getPackageName());
        velocityContext.put("tableComment", table.getTableComment());
        return velocityContext;
    }

    /**
     * 构建渲染DAO.java.vm需要的上下文
     */
    public static VelocityContext buildVelocityContextXDAO(Table table, Module module, List<Module> modules) {
        VelocityContext velocityContext = new VelocityContext();
        for (Module module1 : modules) {
            if (module1.getModuleName().equalsIgnoreCase(ModuleConstants.DOMAIN)) {
                velocityContext.put("DOPackageName", module1.getPackageName() + "." + module1.getFileName());
                velocityContext.put("DOClassName", module1.getFileName());
            }
        }
        velocityContext.put("author", GenConfig.getAuthor());
        velocityContext.put("className", module.getFileName());
        velocityContext.put("packageName", module.getPackageName());
        velocityContext.put("tableComment", table.getTableComment());
        return velocityContext;
    }


    /**
     * 构建渲染BasicDAO.java.vm需要的上下文
     */
    public static VelocityContext buildVelocityContextXBasicDAO(Module module) {
        VelocityContext velocityContext = new VelocityContext();
        velocityContext.put("packageName", module.getPackageName());
        velocityContext.put("className", module.getFileName());
        return velocityContext;
    }

    /**
     * 构建渲染BasicDAO.java.vm需要的上下文
     */
    public static VelocityContext buildVelocityContextXBasicService(Module module) {
        VelocityContext velocityContext = new VelocityContext();
        velocityContext.put("packageName", module.getPackageName());
        return velocityContext;
    }

    /**
     * 构建渲染BasicMapper.xml.vm需要的上下文
     */
    public static VelocityContext buildVelocityContextXBasicMapper(Module module, List<Module> modules) {
        VelocityContext velocityContext = new VelocityContext();
        for (Module module1 : modules) {
            if (module1.getModuleName().equalsIgnoreCase(ModuleConstants.BASIC_DOMAIN)) {
                velocityContext.put("DOPackageName", module1.getPackageName() + "." + module1.getFileName());
            }
            if (module1.getModuleName().equalsIgnoreCase(ModuleConstants.BASIC_DAO)) {
                velocityContext.put("DAOPackageName", module1.getPackageName() + "." + module1.getFileName());
            }
        }
        return velocityContext;
    }

    /**
     * 构建渲染Mapper_BASIC.xml.vm需要的上下文
     */
    public static VelocityContext buildVelocityContextXMapperBasic(Table table, List<GenColumn> columns, Module module, List<Module> modules) {
        VelocityContext velocityContext = new VelocityContext();
        for (Module module1 : modules) {
            if (module1.getModuleName().equalsIgnoreCase(ModuleConstants.DOMAIN_BASIC)) {
                velocityContext.put("do", module1.getPackageName() + "." + module1.getFileName());
            }
            if (module1.getModuleName().equalsIgnoreCase(ModuleConstants.DAO_BASIC)) {
                velocityContext.put("dao", module1.getPackageName() + "." + module1.getFileName());
            }
            if (module1.getModuleName().equalsIgnoreCase(ModuleConstants.BASIC_DAO)) {
                velocityContext.put("basicDAOPackageName", module1.getPackageName() + "." + module1.getFileName());
            }
        }
        velocityContext.put("tableName", table.getTableName());
        velocityContext.put("columns", columns);
        List<GenColumn> collect = MapUtils.filterBasicColumns(columns);
        velocityContext.put("collect", collect);
        return velocityContext;
    }

    /**
     * 构建渲染Mapper_BASIC.xml.vm需要的上下文
     */
    public static VelocityContext buildVelocityContextXMapper(Table table, List<GenColumn> columns, Module module, List<Module> modules) {
        VelocityContext velocityContext = new VelocityContext();
        for (Module module1 : modules) {
            if (module1.getModuleName().equalsIgnoreCase(ModuleConstants.DOMAIN)) {
                velocityContext.put("do", module1.getPackageName() + "." + module1.getFileName());
            }
            if (module1.getModuleName().equalsIgnoreCase(ModuleConstants.DAO) || module1.getModuleName().equalsIgnoreCase(ModuleConstants.DAO_BASIC)) {
                velocityContext.put("dao", module1.getPackageName() + "." + module1.getFileName());
            }
        }
        velocityContext.put("tableName", table.getTableName());
        velocityContext.put("columns", columns);
        List<GenColumn> collect = MapUtils.filterBasicColumns(columns);
        velocityContext.put("collect", collect);
        return velocityContext;
    }


}


















